
//E代表数据存放的是E这个数据类型，E可以以任意其他字母代替。字面意思为Element
public class ArrayMy<E> {
    private E[] data;
    private int size;
//    private int capacity;//arr.length

    public ArrayMy(int capacity) {
        //  java不支持直接new E一个泛型数组,需要强制类型转换一下。
//        data = new E[capacity];
        data = (E[]) new Object[capacity];
        size = 0;
    }

    public ArrayMy() {
        this(10);
    }

    public int getSize() {
        return size;
    }

    public int getCapacity() {
        return data.length;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public void addFirst(E element) {
        add(0, element);
    }

    public void addLast(E element) {
//        if (size == data.length) {
//            throw new IllegalArgumentException("addLast参数错误,array is full");
//        }
//        data[size] = element;//or data[size++]=element
//        size++;
        add(size, element);//上面的几行代码可以用add替换
    }
    // 66 88 99 100,希望把77 放在66之后

    /**
     * 在index的位置插入元素element
     * 先把size-1从后往前挪，挪到待插入位置后，将元素插入到腾空位置。最后将size++
     */

    public void add(int index, E element) {

//        System.out.println(size);
        if (index < 0 || index > size) {
            throw new IllegalArgumentException(" add 参数size is");
        }
        if (size == data.length) {
            resize(2 * data.length);
//            throw new IllegalArgumentException(" add 参数错误,array is full");
        }
//        System.out.printf("size-1 is %d\n", size - 1);
        for (int i = size - 1; i >= index; i--) {
            data[i + 1] = data[i];
        }
        data[index] = element;
        size++;
    }

    private void resize(int newCapacity) {
        E[] newData = (E[]) new Object[newCapacity];
        for (int i = 0; i < size; i++)
            newData[i] = data[i];
        data = newData;
    }

    public void addOrigin(int index, E e) {

        if (size == data.length)
            throw new IllegalArgumentException("Add failed. Array is full.");

        if (index < 0 || index > size)
            throw new IllegalArgumentException("Add failed. Require index >= 0 and index <= size.");

        for (int i = size - 1; i >= index; i--)
            data[i + 1] = data[i];

        data[index] = e;

        size++;
    }

    @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        res.append(String.format("Array size =%d,capacity=%d\n", size, data.length));
        res.append("[");
        for (int i = 0; i < size; i++) {
            res.append(data[i]);
            if (i != size - 1) {
                res.append(",");
            }
        }
        res.append("]");
        return res.toString();

    }

    public E getLast(){
        return get(size-1);
    }

    public E getFirst(){
        return get(0);
    }
    public E get(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("index >0 && index >size");
        }
        return data[index];
    }

    void set(int index, E element) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("index >0 && index >size");
        }
        data[index] = element;
    }

    public boolean contains(E element) {
        for (int i = 0; i < size; i++) {

            //如果做泛型，是对象之间比较，使用equals
            if (data[i].equals(element)) return true;
//            if (data[i] == element) return true;
        }
        return false;
    }

    public int findIndex(E element) {
        for (int i = 0; i < size; i++) {
            if (data[i].equals(element)) return i;
        }
        return -1;
    }

    //与add是相反的过程，先删除，再左移即可
//     @// TODO: 2020/1/7 如果有多个元素相同元素删除 的逻辑，类比redis lrem(count,value)
    public E del(int index) {

        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("index >0 && index >size");
        }
        E ret = data[index];
//        for (int i = index; i < size; i++) {
//            data[i] = data[i + 1];
//        }
        //比如删除第5个，需要从第6个开始，依次把第六个给第五个，把第七个给第六个
        for(int i = index + 1 ; i < size ; i ++)
            data[i - 1] = data[i];
        size--;

        if (size == data.length/2) {
            System.out.format("===========size is %s,data.length=%s\n",size,data.length);
            resize(data.length / 2);
        }
//        data[size] = null;//考虑到引用时的垃圾回收问题，再次指为null比较好。可以引起java的自动垃圾回收机制。loiter objec。闲杂对象。
        return ret;
    }

    public E removeLast() {
        System.out.println(size-1);
        return del(size - 1);
    }

    public E removeFirst() {
        return del(0);
    }

    public int removeElement(E element) {

        int index = findIndex(element);
        if (index != -1) {
            del(index);
        }
//        for (int i = 0; i < data.length; i++) {
//            if (element == data[i]) {
//                del(i);
//                return i;
//            }
//        }
        return index;
    }
}
